package com.webank.maling.ai.documentation;

import com.webank.maling.ai.support.AISupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文档聚合AI服务
 * 负责调用AI模型进行文档聚合分析和内容生成
 *
 * @author diodehe
 */
@Slf4j
@Service
public class AIDocumentationAggregationService {

    @Autowired
    @Qualifier("simpleChatClient")
    private ChatClient chatClient;

    // 聚合分析模板资源
    @Value("classpath:/prompts/aggregation/group-analysis.st")
    private Resource groupAnalysisResource;

    // 内容生成模板资源
    @Value("classpath:/prompts/aggregation/content-generation.st")
    private Resource contentGenerationResource;

    // 重试配置
    private static final int MAX_RETRY_ATTEMPTS = 3;
    private static final long RETRY_DELAY_MS = 1000;

    /**
     * 分析文档分组
     *
     * @param summariesJson 说明书摘要JSON字符串
     * @return 聚合分组列表
     */
    public <T> List<T> analyzeDocumentationGroups(String summariesJson, Type typeReference) {
        try {
            log.info("开始分析文档分组");

            // 构建分组分析提示词
            Prompt prompt = buildGroupAnalysisPrompt(summariesJson);

            // 调用AI服务
            String response = callAIServiceWithRetry(prompt);
            if (response == null || response.trim().isEmpty()) {
                log.error("AI模型返回空响应");
                return List.of();
            }

            // 解析AI响应
            return AISupport.parseAIResponse(response, typeReference);

        } catch (Exception e) {
            log.error("分析文档分组时发生错误", e);
            return List.of();
        }
    }

    /**
     * 生成聚合内容
     *
     * @param aggregationType 聚合类型
     * @param description 聚合描述
     * @param docsContent 文档内容
     * @return 聚合内容对象
     */
    public <T> T generateAggregatedContent(String aggregationType, String description, 
                                         String docsContent, Class<T> responseClass) {
        try {
            log.info("开始生成聚合内容，类型: {}", aggregationType);

            // 构建内容生成提示词
            Prompt prompt = buildContentGenerationPrompt(aggregationType, description, docsContent);

            // 调用AI服务
            String response = callAIServiceWithRetry(prompt);
            if (response == null || response.trim().isEmpty()) {
                log.error("AI模型返回空响应");
                return null;
            }

            // 解析AI响应
            T content = AISupport.parseAIResponse(response, responseClass);
            log.info("成功生成聚合内容，类型: {}", aggregationType);
            return content;

        } catch (Exception e) {
            log.error("生成聚合内容时发生错误，类型: {}", aggregationType, e);
            return null;
        }
    }

    /**
     * 构建分组分析提示词
     */
    private Prompt buildGroupAnalysisPrompt(String summariesJson) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("summariesJson", summariesJson);

        PromptTemplate template = new PromptTemplate(groupAnalysisResource);
        UserMessage userMessage = new UserMessage(template.render(variables));

        return new Prompt(List.of(buildSystemMessage(), userMessage));
    }

    /**
     * 构建内容生成提示词
     */
    private Prompt buildContentGenerationPrompt(String aggregationType, String description, String docsContent) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("aggregationType", aggregationType);
        variables.put("description", description);
        variables.put("docsContent", docsContent);

        PromptTemplate template = new PromptTemplate(contentGenerationResource);
        UserMessage userMessage = new UserMessage(template.render(variables));

        return new Prompt(List.of(buildSystemMessage(), userMessage));
    }

    /**
     * 构建系统消息
     */
    private SystemMessage buildSystemMessage() {
        return new SystemMessage("你是一个专业的文档聚合和分析助手。请严格按照用户要求的JSON格式返回结果，不要添加任何其他内容。");
    }

    /**
     * 带重试机制的AI服务调用
     */
    private String callAIServiceWithRetry(Prompt prompt) {
        Exception lastException = null;

        for (int attempt = 1; attempt <= MAX_RETRY_ATTEMPTS; attempt++) {
            try {
                log.debug("第 {} 次尝试调用AI服务", attempt);

                String result = callAIService(prompt);

                if (result != null && !result.trim().isEmpty()) {
                    log.debug("AI服务调用成功，第 {} 次尝试", attempt);
                    return result;
                }

                log.warn("AI服务返回空内容，第 {} 次尝试", attempt);

            } catch (Exception e) {
                lastException = e;
                log.warn("AI服务调用失败，第 {} 次尝试: {}", attempt, e.getMessage());

                if (attempt < MAX_RETRY_ATTEMPTS) {
                    try {
                        Thread.sleep(RETRY_DELAY_MS * attempt); // 递增延迟
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }

        log.error("AI服务调用失败，已重试 {} 次", MAX_RETRY_ATTEMPTS, lastException);
        return null;
    }

    /**
     * 调用AI服务
     */
    private String callAIService(Prompt prompt) {
        try {
            log.debug("调用 Spring AI ChatClient");

            String response = chatClient.prompt(prompt)
                    .advisors(new SimpleLoggerAdvisor())
                    .call()
                    .content();

            log.debug("AI服务响应成功，内容长度: {}", response != null ? response.length() : 0);
            return response;

        } catch (Exception e) {
            log.error("Spring AI ChatClient 调用失败", e);
            throw new RuntimeException("AI服务调用失败", e);
        }
    }
}
